package com.answer.petsale.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.answer.petsale.common.ErrorCode;
import com.answer.petsale.exception.BusinessException;
import com.answer.petsale.mapper.OrderMapper;
import com.answer.petsale.model.dto.order.OrderCreateRequest;
import com.answer.petsale.model.dto.order.OrderQueryRequest;
import com.answer.petsale.model.entity.Animal;
import com.answer.petsale.model.entity.Order;
import com.answer.petsale.model.entity.User;
import com.answer.petsale.model.vo.OrderVO;
import com.answer.petsale.model.vo.UserVO;
import com.answer.petsale.service.AnimalService;
import com.answer.petsale.service.OrderService;
import com.answer.petsale.service.UserService;
import com.answer.petsale.constant.CommonConstant;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.UUID;

/**
 * 订单服务实现
 * @author answer
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    @Resource
    private AnimalService animalService;

    @Resource
    private UserService userService;

    /**
     * 重构后的方法：用户提交一个“预定申请”（即创建一个待审核的订单）
     */
    @Override
    @Transactional
    public long createOrder(OrderCreateRequest orderCreateRequest, User loginUser) {
        Long animalId = orderCreateRequest.getAnimalId();

        // 使用 synchronized 锁住宠物资源，防止并发申请导致数据不一致
        synchronized (String.valueOf(animalId).intern()) {
            // 1. 查询宠物信息并校验状态
            Animal animal = animalService.getById(animalId);
            if (animal == null) {
                throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "宠物信息不存在");
            }
            // 如果宠物状态为 1 (已售出)，则不能再提交申请
            if (animal.getSaleStatus() == 1) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR, "抱歉，该宠物已被买走");
            }

            // 2. 获取用户最新信息并校验余额是否足够（不扣款）
            User buyer = userService.getById(loginUser.getId());
            if (buyer.getBalance().compareTo(animal.getPrice()) < 0) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR, "您的余额不足以支付，无法提交预定申请");
            }

            // 3. 创建订单对象，并设置为“待审核”状态
            Order newOrder = new Order();
            BeanUtils.copyProperties(orderCreateRequest, newOrder);
            newOrder.setUserId(buyer.getId());
            newOrder.setFinalPrice(animal.getPrice()); // 价格以后端为准
            newOrder.setOrderNumber(UUID.randomUUID().toString().replace("-", ""));
            newOrder.setStatus(0); // 核心修改：状态设为 0 (待审核)

            // 4. 将“待审核”的订单存入数据库
            boolean saveOrderResult = this.save(newOrder);
            if (!saveOrderResult) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "申请提交失败，请重试");
            }

            // 5. 如果宠物原状态为“在售”，则更新为“已被预定”
            if (animal.getSaleStatus() == 0) {
                animal.setSaleStatus(2); // 核心修改：状态设为 2 (已被预定)
                boolean updateAnimalResult = animalService.updateById(animal);
                if (!updateAnimalResult) {
                    throw new BusinessException(ErrorCode.SYSTEM_ERROR, "更新宠物状态失败");
                }
            }

            // 6. 返回新创建的“待审核”订单的ID
            return newOrder.getId();
        }
    }

    /**
     * 新增方法：管理员批准一个订单申请
     * @param orderIdToApprove 要批准的订单ID
     * @return 是否成功
     */
    @Override
    @Transactional
    public boolean approveOrder(long orderIdToApprove) {
        // 1. 获取要批准的订单，并进行严格校验
        Order approvedOrder = this.getById(orderIdToApprove);
        if (approvedOrder == null || approvedOrder.getStatus() != 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "订单不存在或不是待审核状态，无法批准");
        }

        Long animalId = approvedOrder.getAnimalId();
        // 锁住宠物资源，进行后续的独占操作
        synchronized (String.valueOf(animalId).intern()) {
            // 2. 再次校验宠物状态，防止在审核期间被管理员重复操作或已被他人抢先批准
            Animal animal = animalService.getById(animalId);
            if (animal == null || animal.getSaleStatus() == 1) { // 如果宠物不存在或已被售出
                throw new BusinessException(ErrorCode.OPERATION_ERROR, "宠物已被售出，无法完成此批准操作");
            }

            // 3. 获取买家信息，并正式扣款
            User buyer = userService.getById(approvedOrder.getUserId());
            BigDecimal petPrice = animal.getPrice();
            if (buyer.getBalance().compareTo(petPrice) < 0) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR, "该用户余额已不足以完成交易，无法批准");
            }
            buyer.setBalance(buyer.getBalance().subtract(petPrice));
            boolean updateUserResult = userService.updateById(buyer);
            if (!updateUserResult) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "扣除用户余额失败，交易已回滚");
            }

            // 4. 更新被批准的订单状态为“已完成”
            approvedOrder.setStatus(1); // 1: 已完成
            approvedOrder.setPayTime(new java.util.Date());
            boolean updateApprovedOrderResult = this.updateById(approvedOrder);
            if(!updateApprovedOrderResult){
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "更新已批准订单状态失败");
            }

            // 5. 批量将该宠物其他所有“待审核”订单的状态更新为“未通过”
            Order updateOrderEntity = new Order();
            updateOrderEntity.setStatus(2); // 2: 未通过/已取消
            QueryWrapper<Order> otherOrdersWrapper = new QueryWrapper<>();
            otherOrdersWrapper.eq("animalId", animalId)
                    .eq("status", 0);
            baseMapper.update(updateOrderEntity, otherOrdersWrapper);

            // 6. 更新宠物最终状态为“已售出”
            animal.setSaleStatus(1); // 1: 已售出
            boolean updateAnimalResult = animalService.updateById(animal);
            if (!updateAnimalResult) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "更新宠物最终状态失败");
            }

            return true;
        }
    }

    @Override
    public QueryWrapper<Order> getQueryWrapper(OrderQueryRequest orderQueryRequest) {
        if (orderQueryRequest == null) {
            return new QueryWrapper<>();
        }

        Integer status = orderQueryRequest.getStatus();
        String sortField = orderQueryRequest.getSortField();
        String sortOrder = orderQueryRequest.getSortOrder();

        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(status != null, "status", status);

        boolean isAsc = CommonConstant.SORT_ORDER_ASC.equals(sortOrder);
        queryWrapper.orderBy(StringUtils.isNotBlank(sortField), isAsc, sortField);

        return queryWrapper;
    }

    @Override
    public OrderVO getOrderVO(Order order) {
        if (order == null) {
            return null;
        }
        OrderVO orderVO = new OrderVO();
        BeanUtils.copyProperties(order, orderVO);

        Animal animal = animalService.getById(order.getAnimalId());
        if (animal != null) {
            OrderVO.AnimalInfoVO animalInfoVO = new OrderVO.AnimalInfoVO();
            BeanUtils.copyProperties(animal, animalInfoVO);
            orderVO.setAnimalInfo(animalInfoVO);
        }

        User buyer = userService.getById(order.getUserId());
        if (buyer != null) {
            UserVO buyerVO = new UserVO();
            BeanUtils.copyProperties(buyer, buyerVO);
            orderVO.setBuyerInfo(buyerVO);
        }

        return orderVO;
    }

    // START: 新增代码 (将此整个方法添加到 approveOrder 方法的后面)
    /**
     * 新增方法：管理员拒绝一个订单申请
     * @param orderIdToReject 要拒绝的订单ID
     * @param reason 拒绝的理由
     * @return 是否成功
     */
    @Override
    @Transactional
    public boolean rejectOrder(long orderIdToReject, String reason) {
        // 1. 获取要拒绝的订单，并进行严格校验
        Order orderToReject = this.getById(orderIdToReject);
        if (orderToReject == null || orderToReject.getStatus() != 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "订单不存在或不是待审核状态，无法拒绝");
        }

        // 2. 更新订单状态为“未通过”，并记录拒绝理由
        orderToReject.setStatus(2); // 2: 未通过/已取消
        orderToReject.setRejectionReason(reason); // 记录拒绝理由
        boolean updateOrderResult = this.updateById(orderToReject);
        if (!updateOrderResult) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "更新订单状态为拒绝失败");
        }

        // 3. 将宠物状态恢复为“在售”，以便其他人可以申请
        Long animalId = orderToReject.getAnimalId();
        // 使用与 approveOrder 中相同的锁，确保线程安全
        synchronized (String.valueOf(animalId).intern()) {
            Animal animal = animalService.getById(animalId);
            // 只有当宠物确实处于“已被预定”状态时才改回“在售”，防止误操作
            if (animal != null && animal.getSaleStatus() == 2) {
                animal.setSaleStatus(0); // 0: 在售
                boolean updateAnimalResult = animalService.updateById(animal);
                if (!updateAnimalResult) {
                    throw new BusinessException(ErrorCode.SYSTEM_ERROR, "恢复宠物为在售状态失败");
                }
            }
        }

        return true;
    }
    // END: 新增代码



}